如果你希望在多个类中使用日志功能,而不希望在每个类中重复编写日志的注入逻辑,可以考虑以下几种更简化的方法:
csharp
複製程式碼
public class BaseLogger
{
protected readonly ILogger _logger;
public BaseLogger(ILogger<BaseLogger> logger)
{
_logger = logger;
}
// 你可以在这里添加通用的日志记录方法
}
public class DapperSql : BaseLogger
{
public DapperSql(ILogger logger) : base(logger)
{
// 其他初始化逻辑
}
}
public class z_sqlDepartments : DapperSql
{
public z_sqlDepartments(ILogger logger) : base(logger)
{
// 其他初始化逻辑
}
}
2. 使用装饰器模式
你可以创建一个日志装饰器,它在调用原始类方法之前和之后记录日志。这样,你只需对原始类进行包装,而不必修改原始类的实现。
csharp
複製程式碼
public class LoggingDecorator : IDapperSql
{
private readonly IDapperSql _inner;
private readonly ILogger<LoggingDecorator> _logger;
public LoggingDecorator(IDapperSql<TEntity> inner, ILogger<LoggingDecorator<TEntity>> logger)
{
_inner = inner;
_logger = logger;
}
public async Task DeleteAsync(int id)
{
// 日志记录
_logger.LogInformation($"Deleting record with ID: {id}");
await _inner.DeleteAsync(id);
_logger.LogInformation($"Successfully deleted record with ID: {id}");
}
// 其他 IDapperSql<TEntity> 方法实现
}
然后在 Program.cs 中注册装饰器:
csharp
複製程式碼
builder.Services.AddScoped(typeof(IDapperSql<>), typeof(LoggingDecorator<>));
3. 使用 AOP(面向切面编程)
使用 AOP,可以在不修改原始类代码的情况下添加日志记录。比如使用一些库(如 PostSharp 或 Castle DynamicProxy)来自动处理日志记录。
csharp
複製程式碼
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDapperSqlWithLogging(this IServiceCollection services)
{
services.AddScoped(typeof(IDapperSql<>), typeof(DapperSql<>));
services.AddScoped(typeof(LoggingDecorator<>)); // 添加装饰器
return services;
}
}
在 Program.cs 中调用:
csharp
複製程式碼
builder.Services.AddDapperSqlWithLogging();
使用装饰器模式来实现日志记录功能,您可以按照以下步骤修改 DapperSql<TEntity> 类和装饰器类。这个过程将使日志记录逻辑从 DapperSql<TEntity> 中分离出来,简化其代码。
1. 创建装饰器类
首先,您需要创建一个装饰器类,它将实现与 DapperSql<TEntity> 相同的接口并包装其功能。这里是一个基本示例:
csharp
複製程式碼
public class DapperSqlLoggingDecorator<TEntity> : IDapperSql<TEntity> where TEntity : class
{
private readonly IDapperSql<TEntity> _inner;
private readonly ILogger<DapperSqlLoggingDecorator<TEntity>> _logger;
public DapperSqlLoggingDecorator(IDapperSql<TEntity> inner, ILogger<DapperSqlLoggingDecorator<TEntity>> logger)
{
_inner = inner;
_logger = logger;
}
public async Task DeleteAsync(int id)
{
_logger.LogInformation($"Attempting to delete record with ID: {id}");
try
{
await _inner.DeleteAsync(id);
_logger.LogInformation($"Successfully deleted record with ID: {id}");
}
catch (Exception ex)
{
_logger.LogError(ex, $"Error occurred while trying to delete record with ID: {id}");
throw;
}
}
// 其他 IDapperSql<TEntity> 方法实现
// 您需要在这里实现 DapperSql<TEntity> 接口的其他方法
}
2. 修改 DapperSql<TEntity>
然后,您可以简化 DapperSql<TEntity> 的构造函数,移除日志记录的相关代码:
csharp
複製程式碼
public class DapperSql<TEntity> : BaseClass, IDapperSql<TEntity> where TEntity : class
{
public DapperRepository dpr { get; set; } = new DapperRepository();
public TEntity EntityObject { get { return (TEntity)Activator.CreateInstance(typeof(TEntity)); } }
public string EntityName { get { return typeof(TEntity).Name; } }
// 其他方法不变...
}
3. 注册依赖项
在 Program.cs 中,您需要注册 DapperSql<TEntity> 和它的装饰器:
csharp
複製程式碼
builder.Services.AddScoped(typeof(IDapperSql<>), typeof(DapperSql<>));
builder.Services.Decorate(typeof(IDapperSql<>), typeof(DapperSqlLoggingDecorator<>));
使用 Decorate 方法需要确保您已引入必要的 NuGet 包(如 Scrutor),因为 .NET Core 默认不支持装饰器模式。
4. 使用装饰器
现在,您可以在需要使用 IDapperSql<TEntity> 的地方注入该接口。日志记录将自动应用于 DeleteAsync 方法和其他实现。